#include "SFilterTermRange.h"

#include <QHBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QRegExpValidator>

#include "DualCalendars.h"

namespace {
const int gap = 4;
const int editWidth = 80;
const int buttonWidth = 40;
const int lineHeight = 24;

enum eChild { idchild_edit_left = 1001, idchild_edit_right };

class MyValidator : public QValidator {
 public:
  MyValidator(QObject* parent = nullptr) : QValidator(parent) {}
  State validate(QString& input, int&) const override {
    input = input.toUpper();
    return QValidator::Acceptable;
  }
};

}  // namespace

namespace {}

SFilterTermRange::SFilterTermRange(QWidget* p) : QFrame(p) { setupUI(); }

void SFilterTermRange::setupUI() {
  QHBoxLayout* layout = new QHBoxLayout(this);
  layout->setContentsMargins(0, 0, 0, 0);
  layout->setSpacing(gap);

  QString szExp = "^[0-9]{1,3}[.][0-9]{1,2}[yY]|^[0-9]{1,4}[dmyDMY]";
  m_edtLeft = new SClickedEdit(this, idchild_edit_left);
  m_edtLeft->setFixedSize(editWidth, lineHeight);
  m_edtLeft->setValidator(new QRegExpValidator(QRegExp(szExp), this));
  m_edtRight = new SClickedEdit(this, idchild_edit_right);
  m_edtRight->setFixedSize(editWidth, lineHeight);
  m_edtRight->setValidator(new QRegExpValidator(QRegExp(szExp), this));

  m_calDate = new DualCalendars(this, true);
  m_calDate->hide();

  m_btnSwitch = new QPushButton(this);
  m_btnSwitch->setFixedSize(lineHeight, lineHeight);
  m_btnFilter = new QPushButton(tr("筛选", "Filter"), this);
  m_btnFilter->setFixedSize(buttonWidth, lineHeight);

  m_strStyleYearDate = QString(
      "QPushButton {image:url(:/widgets/image/calendar/calendar_normal.png);}");
  m_strStyleCalendar = QString(
      "QPushButton {image:url(:/widgets/image/dayyear/dayyear_normal.png);}");

  if (m_bYearDayMode)
    m_btnSwitch->setStyleSheet(m_strStyleYearDate);
  else
    m_btnSwitch->setStyleSheet(m_strStyleCalendar);

  layout->addWidget(m_edtLeft);
  layout->addWidget(m_btnSwitch);
  layout->addWidget(m_edtRight);
  layout->addWidget(m_btnFilter);
  layout->addStretch();

  connect(m_edtLeft, &QLineEdit::textChanged, this, &SFilterTermRange::toUpper);
  connect(m_edtRight, &QLineEdit::textChanged, this,
          &SFilterTermRange::toUpper);
  connect(m_edtLeft, &SClickedEdit::clicked, this,
          &SFilterTermRange::onEditClick);
  connect(m_edtRight, &SClickedEdit::clicked, this,
          &SFilterTermRange::onEditClick);
  connect(m_btnSwitch, &QPushButton::clicked, this,
          &SFilterTermRange::onBtnSwitchClick);
  connect(m_calDate, &DualCalendars::dateSelected, this,
          &SFilterTermRange::onCalendarSelected);
  connect(m_btnFilter, &QPushButton::clicked, this,
          &SFilterTermRange::onFilterButtonClick);
}

void SFilterTermRange::toUpper(const QString& str) {
  QLineEdit* le = qobject_cast<QLineEdit*>(sender());
  if (!le) return;
  le->setText(str.toUpper());
}

void SFilterTermRange::clear() {
  m_dateStart = m_dateEnd = 0;
  m_strTermStart = m_strTermEnd = "";
  m_edtLeft->clear();
  m_edtRight->clear();
}

void SFilterTermRange::onEditClick(int id) {
  if (m_bYearDayMode) return;
  if (!m_calDate) return;

  QWidget* pEdit = nullptr;
  switch (id) {
    case idchild_edit_left:
      pEdit = m_edtLeft;
      m_bLeftCaleValid = true;
      break;
    case idchild_edit_right:
      pEdit = m_edtRight;
      m_bLeftCaleValid = false;
      break;
    default:
      break;
  }
  if (!pEdit) return;

  int w = m_calDate->width();
  int h = m_calDate->height();

  QPoint p = pEdit->pos();
  int x = mapToGlobal(p).x();
  int y = mapToGlobal(p).y();
  QRect rcInner = pEdit->rect();
  rcInner.moveTo(x, y);
  m_calDate->setInnerRect(rcInner);
  m_calDate->setGeometry(x, y + rcInner.height(), w, h);
  m_calDate->show();
}

void SFilterTermRange::onBtnSwitchClick() {
  m_bYearDayMode = !m_bYearDayMode;
  m_dateStart = m_dateEnd = 0;
  m_strTermStart = m_strTermEnd = "";
  QString strStyle;
  if (m_bYearDayMode) {
    m_btnSwitch->setStyleSheet(m_strStyleYearDate);
    m_edtLeft->clear();
    m_edtLeft->setReadOnly(false);
    m_edtRight->clear();
    m_edtRight->setReadOnly(false);
  } else {
    m_btnSwitch->setStyleSheet(m_strStyleCalendar);
    m_edtLeft->clear();
    m_edtLeft->setReadOnly(true);
    m_edtRight->clear();
    m_edtRight->setReadOnly(true);
  }
}

void SFilterTermRange::onCalendarSelected(int nDate) {
  if (m_bLeftCaleValid) {
    QString szDate = QString("%1").arg(nDate);
    m_edtLeft->setText(szDate);

    m_dateStart = nDate;
    if (m_dateEnd > 0 && m_dateEnd < nDate) {
      m_dateEnd = m_dateStart;
      m_edtRight->setText(szDate);
    }
  } else {
    if (m_dateStart > nDate) {
      nDate = m_dateStart;
    }
    m_dateEnd = nDate;
    QString szDate = QString("%1").arg(nDate);
    m_edtRight->setText(szDate);
  }
}

void SFilterTermRange::onFilterButtonClick() {
  if (m_bYearDayMode) {
    m_dateStart = m_dateEnd = 0;
    m_strTermStart = m_edtLeft->text();
    m_strTermEnd = m_edtRight->text();
  } else {
    m_strTermStart = m_strTermEnd = "";
  }
  emit changed();
}

void SFilterTermRange::getTermRange(QString& strStart, QString& strEnd,
                                    bool& bYearDayMode) {
  bYearDayMode = m_bYearDayMode;
  strStart = strEnd = "";
  if (bYearDayMode) {
    strStart = m_strTermStart;
    strEnd = m_strTermEnd;
  } else {
    if (m_dateStart > 0) strStart = QString("%1").arg(m_dateStart);
    ;
    if (m_dateEnd > 0) strEnd = QString("%1").arg(m_dateEnd);
  }
}
